package com.pku.smart.trade.service.impl;

import com.alibaba.fastjson.JSON;
import com.pku.smart.constant.PayConstant;
import com.pku.smart.log.MyLog;
import com.pku.smart.trade.entity.TradePayOrder;
import com.pku.smart.trade.entity.TradeRefundOrder;
import com.pku.smart.trade.enums.TradePayRefundStatusEnum;
import com.pku.smart.trade.enums.TradePayStatusEnum;
import com.pku.smart.trade.service.ITradePayOrderService;
import com.pku.smart.trade.service.ITradeRefundOrderService;
import com.pku.smart.trade.vopackage.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;
import java.util.Map;

public class PaymentManagerServiceBase {

    private static final MyLog _log = MyLog.getLog(PaymentManagerServiceBase.class);

    @Autowired
    ITradePayOrderService tradePayOrderService;

    @Autowired
    ITradeRefundOrderService tradeRefundOrderService;

    /**
     * 条码支付结果分析
     *
     * @param resultMap
     * @return
     */
    @Deprecated
    public VoResTradePayment getPayResultMap(Map resultMap, VoResPayCode responseVo) {
        VoResTradePayment tradeResult = new VoResTradePayment();

        responseVo.setErrCode((String) resultMap.get("errCode"));
        responseVo.setErrCodeDes((String) resultMap.get("errMsg"));

        String retCode = (String) resultMap.getOrDefault("retCode", "");
        if (PayConstant.TRADE_STATUS_SUCCESS.equalsIgnoreCase(retCode)) {
            tradeResult.setRetCode(PayConstant.TRADE_STATUS_SUCCESS);

            String mchId = responseVo.getMchId();
            String mchOrderNo = responseVo.getMchOrderNo();
            String channelOrderNo = String.valueOf(resultMap.get("channelOrderNo"));
            _log.info("支付成功，更新订单表。" + channelOrderNo);
            completeSuccessOrder(mchId, mchOrderNo, channelOrderNo);

            responseVo.setChannelOrderNo(channelOrderNo);
        } else if (PayConstant.TRADE_STATUS_FAILED.equalsIgnoreCase(retCode)) {
            _log.info("失败");
            tradeResult.setRetCode(PayConstant.TRADE_STATUS_FAILED);
        } else if (PayConstant.TRADE_STATUS_TIMEOUT.equalsIgnoreCase(retCode)) {
            _log.info("超时");
            tradeResult.setRetCode(PayConstant.TRADE_STATUS_FAILED);
        }

        tradeResult.setRetData(responseVo);
        _log.info("打印：" + JSON.toJSONString(tradeResult));
        return tradeResult;
    }

    /**
     * 扫码支付结果分析
     *
     * @param resultMap
     * @param responseVo
     * @return
     */
    public VoResTradePayment getPreCreateResultMap(Map resultMap, VoResPayScan responseVo) {
        VoResTradePayment tradeResult = new VoResTradePayment();

        responseVo.setErrCode((String) resultMap.get("errCode"));
        responseVo.setErrCodeDes((String) resultMap.get("errMsg"));

        String retCode = (String) resultMap.getOrDefault("retCode", "");
        if (PayConstant.TRADE_STATUS_SUCCESS.equalsIgnoreCase(retCode)) {
            String mchId = responseVo.getMchId();
            String mchOrderNo = responseVo.getMchOrderNo();
            String codeUrl = String.valueOf(resultMap.get("codeUrl"));
            responseVo.setCodeUrl(codeUrl);
            completePayingOrder(mchId, mchOrderNo, null, codeUrl);
            tradeResult.setRetCode(PayConstant.TRADE_STATUS_SUCCESS);
        } else {
            tradeResult.setRetCode(PayConstant.TRADE_STATUS_FAILED);
        }

        tradeResult.setRetData(responseVo);
        _log.info("打印：" + JSON.toJSONString(tradeResult));
        return tradeResult;
    }

    /**
     * 支付订单查询
     *
     * @param resultMap
     * @param responseVo
     * @return
     */
    public VoResTradePayment getQueryResultMap(Map resultMap, VoResQueryPay responseVo) {
        VoResTradePayment tradeResult = new VoResTradePayment();

        responseVo.setErrCode((String) resultMap.get("errCode"));
        responseVo.setErrCodeDes((String) resultMap.get("errMsg"));

        String retCode = (String) resultMap.getOrDefault("retCode", "");
        if (!PayConstant.TRADE_STATUS_SUCCESS.equalsIgnoreCase(retCode)) {
            tradeResult.setRetCode(PayConstant.TRADE_STATUS_FAILED);
            tradeResult.setRetData(responseVo);
            return tradeResult;
        }

        String tradeStatus = (String) resultMap.get("tradeStatus");
        String channelOrderNo = (String) resultMap.get("channelOrderNo");
        if (TradePayStatusEnum.PAY_STATUS_SUCCESS.name().equalsIgnoreCase(tradeStatus)) {
            responseVo.setInvokeStatus(TradePayStatusEnum.PAY_STATUS_SUCCESS.getCode().toString());
            responseVo.setChannelOrderNo(channelOrderNo);
            _log.info("支付成功，更新订单表。" + channelOrderNo);
            String mchId = responseVo.getMchId();
            String mchOrderNo = responseVo.getMchOrderNo();
            completeSuccessOrder(mchId, mchOrderNo, channelOrderNo);
        } else if (TradePayStatusEnum.PAY_STATUS_PAYING.name().equalsIgnoreCase(tradeStatus)) {
            responseVo.setInvokeStatus(TradePayStatusEnum.PAY_STATUS_PAYING.getCode().toString());
            responseVo.setChannelOrderNo(channelOrderNo);
            String mchId = responseVo.getMchId();
            String mchOrderNo = responseVo.getMchOrderNo();
            completePayingOrder(mchId, mchOrderNo, channelOrderNo, null);
            responseVo.setErrCode((String) resultMap.get("errCode"));
            responseVo.setErrCodeDes((String) resultMap.get("errMsg"));
        } else {
            responseVo.setInvokeStatus(TradePayStatusEnum.PAY_STATUS_FAILED.getCode().toString());
            responseVo.setErrCode((String) resultMap.get("errCode"));
            responseVo.setErrCodeDes((String) resultMap.get("errMsg"));
        }

        tradeResult.setRetCode(PayConstant.TRADE_STATUS_SUCCESS);
        tradeResult.setRetData(responseVo);
        _log.info("打印：" + JSON.toJSONString(tradeResult));

        return tradeResult;
    }

    /**
     * 订单撤销
     *
     * @param resultMap
     * @param responseVo
     * @return 成功or失败
     */
    public VoResTradePayment getCancelResultMap(Map resultMap, VoResRefund responseVo) {
        VoResTradePayment tradeResult = new VoResTradePayment();

        responseVo.setErrCode((String) resultMap.get("errCode"));
        responseVo.setErrCodeDes((String) resultMap.get("errMsg"));

        if (!PayConstant.TRADE_STATUS_SUCCESS.equalsIgnoreCase((String) resultMap.getOrDefault("retCode", ""))) {
            tradeResult.setRetCode(PayConstant.TRADE_STATUS_FAILED);
            tradeResult.setRetData(responseVo);
        } else {
            responseVo.setChannelRefundNo(String.valueOf(resultMap.get("channelRefundOrderNo")));
            tradeResult.setRetCode(PayConstant.TRADE_STATUS_SUCCESS);
        }

        tradeResult.setRetData(responseVo);
        _log.info("打印：" + JSON.toJSONString(tradeResult));
        return tradeResult;
    }

    /**
     * 退款查询
     *
     * @param resultMap
     * @param responseVo
     * @return
     */
    public VoResTradePayment getQueryRefundResultMap(Map resultMap, VoResQueryRefund responseVo) {
        VoResTradePayment tradeResult = new VoResTradePayment();

        responseVo.setErrCode((String) resultMap.get("errCode"));
        responseVo.setErrCodeDes((String) resultMap.get("errMsg"));

        if (!PayConstant.TRADE_STATUS_SUCCESS.equalsIgnoreCase((String) resultMap.getOrDefault("retCode", ""))) {
            tradeResult.setRetCode(PayConstant.TRADE_STATUS_FAILED);
            tradeResult.setRetData(responseVo);
            return tradeResult;
        }

        String tradeStatus = (String) resultMap.get("tradeStatus");
        if (TradePayRefundStatusEnum.REFUND_STATUS_SUCCESS.name().equalsIgnoreCase(tradeStatus)) {
            String channelOrderNo = responseVo.getChannelOrderNo();
            responseVo.setInvokeStatus(TradePayRefundStatusEnum.REFUND_STATUS_SUCCESS.getCode().toString());
            responseVo.setChannelOrderNo(channelOrderNo);
        } else {
            responseVo.setInvokeStatus(TradePayRefundStatusEnum.REFUND_STATUS_FAILED.getCode().toString());
            responseVo.setErrCode((String) resultMap.get("errCode"));
            responseVo.setErrCodeDes((String) resultMap.get("errMsg"));
        }

        tradeResult.setRetCode(PayConstant.TRADE_STATUS_SUCCESS);
        tradeResult.setRetData(responseVo);
        _log.info("打印：" + JSON.toJSONString(tradeResult));

        return tradeResult;
    }

    /**
     * 退款
     *
     * @param resultMap
     * @param responseVo
     * @return
     */
    public VoResTradePayment getRefundResultMap(Map resultMap, VoResRefund responseVo) {
        VoResTradePayment tradeResult = new VoResTradePayment();

        responseVo.setErrCode((String) resultMap.get("errCode"));
        responseVo.setErrCodeDes((String) resultMap.get("errMsg"));

        if (!PayConstant.TRADE_STATUS_SUCCESS.equalsIgnoreCase((String) resultMap.getOrDefault("retCode", ""))) {
            tradeResult.setRetCode(PayConstant.TRADE_STATUS_FAILED);
        } else {
            String channelRefundOrderNo = String.valueOf(resultMap.get("channelRefundOrderNo"));
            responseVo.setChannelRefundNo(channelRefundOrderNo);
            tradeResult.setRetCode(PayConstant.TRADE_STATUS_SUCCESS);
            completeSuccessRefundOrder(responseVo.getMchId(),responseVo.getMchOrderNo(),responseVo.getChannelOrderNo(),responseVo.getMchRefundNo(),channelRefundOrderNo);
        }

        tradeResult.setRetData(responseVo);
        _log.info("打印：" + JSON.toJSONString(tradeResult));
        return tradeResult;
    }

    /**
     * 扫码支付结果分析
     *
     * @param resultMap
     * @param responseVo
     * @return
     */
    public VoResTradePayment getWapPayResultMap(Map resultMap, VoResPayWap responseVo) {
        VoResTradePayment tradeResult = new VoResTradePayment();

        responseVo.setErrCode((String) resultMap.get("errCode"));
        responseVo.setErrCodeDes((String) resultMap.get("errMsg"));

        String retCode = (String) resultMap.getOrDefault("retCode", "");
        if (PayConstant.TRADE_STATUS_SUCCESS.equalsIgnoreCase(retCode)) {
            String mchId = responseVo.getMchId();
            String mchOrderNo = responseVo.getMchOrderNo();
            String body = String.valueOf(resultMap.get("body"));
            responseVo.setCodeUrl(body);

            //completePayingOrder(mchId, mchOrderNo, channelOrderNo, null);
            tradeResult.setRetCode(PayConstant.TRADE_STATUS_SUCCESS);
        } else {
            tradeResult.setRetCode(PayConstant.TRADE_STATUS_FAILED);
        }

        tradeResult.setRetData(responseVo);
        _log.info("打印：" + JSON.toJSONString(tradeResult));
        return tradeResult;
    }

    /**
     * 更新扫码支付 二维码
     *
     * @param mchId
     * @param mchOrderNo
     * @param codeUrl
     */
    private void completePayingOrder(String mchId, String mchOrderNo, String channelOrderNo, String codeUrl) {
        TradePayOrder tradePayOrder = tradePayOrderService.getTradePayOrder(mchId, mchOrderNo);
        tradePayOrder.setErrCode("");
        if (StringUtils.isNotBlank(codeUrl)) {
            tradePayOrder.setAuthCode(codeUrl);
            _log.info("扫码支付更新二维码：" + codeUrl);
        }
        if (StringUtils.isNotBlank(channelOrderNo)) {
            tradePayOrder.setChannelOrderNo(channelOrderNo);
            _log.info("查询更新渠道订单号：" + channelOrderNo);
        }
        tradePayOrder.setStatus(PayConstant.PAY_STATUS_PAYING);
        tradePayOrder.setInvokeStatus(TradePayStatusEnum.PAY_STATUS_PAYING.name());
        tradePayOrderService.updateTradePayOrder(tradePayOrder);
        _log.info("订单{}更新二维码成功.", mchOrderNo);
    }

    /**
     * 支付成功方法
     *
             * @param mchId
     * @param mchOrderNo
     * @param channelOrderNo
     */
    private void completeSuccessOrder(String mchId, String mchOrderNo, String channelOrderNo) {
        TradePayOrder tradePayOrder = tradePayOrderService.getTradePayOrder(mchId, mchOrderNo);
        tradePayOrder.setErrCode("");
        tradePayOrder.setStatus(PayConstant.PAY_STATUS_SUCCESS);
        if (StringUtils.isNotBlank(channelOrderNo)) {
            tradePayOrder.setChannelOrderNo(channelOrderNo);
        }
        tradePayOrder.setInvokeStatus(TradePayStatusEnum.PAY_STATUS_SUCCESS.name());
        tradePayOrder.setPaySuccTime(System.currentTimeMillis());
        tradePayOrderService.updateTradePayOrder(tradePayOrder);
        _log.info("订单{}支付成功.", mchOrderNo);
    }

    /**
     * 退款成功
     * @param mchId
     * @param mchOrderNo
     * @param channelOrderNo
     * @param mchRefundNo
     * @param channelRefundNo
     */
    private void completeSuccessRefundOrder(String mchId, String mchOrderNo, String channelOrderNo, String mchRefundNo, String channelRefundNo) {
        TradeRefundOrder refundOrder = tradeRefundOrderService.getTradeRefundOrder(mchId,mchOrderNo,mchRefundNo);
        refundOrder.setStatus(TradePayRefundStatusEnum.REFUND_STATUS_SUCCESS.getCode());
        refundOrder.setResult(TradePayRefundStatusEnum.REFUND_STATUS_SUCCESS.getDesc());
        if (StringUtils.isBlank(refundOrder.getChannelOrderNo())) {
            refundOrder.setChannelOrderNo(channelOrderNo);
        }
        tradeRefundOrderService.updateTradeRefundOrder(refundOrder);
    }
}
